#ifndef __LPDDR5_H__
#define __LPDDR5_H__

#include "main.h"
#include "scu.h"

#define DDR0_CSR_ADDR 				(0x120000000)
// #define DDR0_CSR_ADDR 				(0x130000000)

#define DDRx_CTRL_ADDR 				(0x00000000)
#define DDRx_SGR_ADDR 				(0x00800000)
#define DDRx_PHY_ADDR 				(0x01000000)

#define DDRx_CTRL_REGB_FREQ0_CH0	(0x00000000)
#define DDRx_CTRL_REGB_DDRC_CH0		(0x00010000)
#define DDRx_CTRL_REGB_ARB_PORT0	(0x00020000)
#define DDRx_CTRL_REGB_ARB_PORT1	(0x00021000)
#define DDRx_CTRL_REGB_ADDR_MAP0	(0x00030000)

// #define TARGET_FREQ 					(0x0e10)//for 3600 MHz fail
// #define TARGET_FREQ 					(0x1068)//for 4200 MHz fail
// #define TARGET_FREQ 					(0x1194)//for 4500 MHz pass
#define TARGET_FREQ 					(0x12c0)//for 4800 MHz pass
// #define TARGET_FREQ 					(0x1388)//for 5000 MHz pass
// #define TARGET_FREQ 					(0x13EC)//for 5100 MHz pass
// #define TARGET_FREQ 					(0x1450)//for 5200 MHz fail
// #define TARGET_FREQ 					(0x1518)//for 5400 MHz fail
// #define TARGET_FREQ 					(0x15E0)//for 5600 MHz fail
// #define TARGET_FREQ 					(0x1770)//for 6000 MHz fail
#define PLL_FREQ_IN 					(0x1A)
#define PLL_BYPASS_EN 					(0x1)
#define PLL_BYPASS_DIS 					(0x0)
#define PHY_TRAINING_EN					(0x1)
#define PHY_TRAINING_DIS				(0x0)
#define COMMON_BUS_TRAINING_EN			(0x1)
#define COMMON_BUS_TRAINING_DIS			(0x0)
#define CK2WCK_TRAINING_EN				(0x1)
#define CK2WCK_TRAINING_DIS				(0x0)
#define PHY_RD_TRAINING_EN				(0x1)
#define PHY_RD_TRAINING_DIS				(0x0)
#define PHY_WR_TRAINING_EN				(0x1)
#define PHY_WR_TRAINING_DIS				(0x0)
#define PHY_PRE_RD_TRAINING_EN			(0x1)
#define PHY_PRE_RD_TRAINING_DIS			(0x0)
#define PHY_PRE_WR_TRAINING_EN			(0x1)
#define PHY_PRE_WR_TRAINING_DIS			(0x0)


void perh_reg_wr(unsigned int master, unsigned long long addr, unsigned int wdata, unsigned int strb);
unsigned int perh_reg_rd(unsigned int master, unsigned long long addr);
void pll_setting(unsigned int pll_fin, unsigned int target_freq, unsigned int bypass_en);
void lpddr5_lf_initial(unsigned int pll_fin, unsigned int pll_fout, unsigned int bypass_en);
void lpddr5_hf_initial(unsigned int pll_fin, unsigned int pll_fout, unsigned int bypass_en, unsigned int phy_training);
void lpddr5_ctrl_static_reg_config(unsigned int phy_training, unsigned int target_freq);
void lpddr5_ctrl_static_reg_config_lf(unsigned int phy_training, unsigned int target_freq);
void lpddr5_ctrl_static_reg_config_hf(unsigned int phy_training, unsigned int target_freq);
void lpddr5_ctrl_initial_complete();
void lpddr5_mrw_config(unsigned int target_freq);
void lpddr5_ctrl_dynamic_reg_config();
void lpddr5_mrw(unsigned int mr_addr,unsigned int mr_value);
unsigned int lpddr5_mrr(unsigned int mr_addr);
void lpddr5_freq_wl_rl_trans(unsigned int target_freq);
void pll_direct(unsigned int pll_fin,unsigned int target_freq);
void lpddr5_phy_training(unsigned int phy_training, unsigned int target_freq,unsigned int phy_hw_cbt,unsigned int phy_wrlvl,unsigned int phy_rd,unsigned int phy_wr,unsigned int phy_prbs_rd,unsigned int phy_prbs_wr);
void samsung_common_setting_before_training(unsigned int target_freq);
void samsung_hwcal_cbt(unsigned int target_freq);
void samsung_wrlvl(unsigned int target_freq);
void samsung_rd(unsigned int target_freq);
void samsung_wr(unsigned int target_freq);
void samsung_prbs_rd(unsigned int target_freq);
void samsung_prbs_wr(unsigned int target_freq);
#define DELAY(delay_value) \
	do{ \
	volatile unsigned int delay_value_1 = delay_value;  \
	while (delay_value_1--); \
	}while(0) \
		;

#endif //__LPDDR5_H__